using System;
using System.Drawing;
using System.Windows.Forms;
using System.Text;

public class MessageWindow : System.Windows.Forms.Form
{

	#region " Windows Form Designer generated code "

	public MessageWindow() : base()
	{

		//This call is required by the Windows Form Designer.
		InitializeComponent();

		//Add any initialization after the InitializeComponent() call
	}

	//Form overrides dispose to clean up the component list.
	protected override void Dispose(bool disposing)
	{
		if (disposing)
		{
			if ((components != null))
			{
				components.Dispose();
			}
		}
		base.Dispose(disposing);
	}

	//Required by the Windows Form Designer
	private System.ComponentModel.IContainer components;

	//NOTE: The following procedure is required by the Windows Form Designer
	//It can be modified using the Windows Form Designer.  
	//Do not modify it using the code editor.
	internal System.Windows.Forms.Button btnSend;
	internal System.Windows.Forms.RichTextBox rtbChat;
	internal System.Windows.Forms.TextBox txtMessage;
	internal System.Windows.Forms.ContextMenu mnuRichText;
	internal System.Windows.Forms.MenuItem mnuCopy;
	internal System.Windows.Forms.MenuItem mnuClear;
	internal System.Windows.Forms.MenuItem mnuSep1;
	[System.Diagnostics.DebuggerStepThrough()]
	private void InitializeComponent()
	{
		System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MessageWindow));
		this.btnSend = new System.Windows.Forms.Button();
		this.rtbChat = new System.Windows.Forms.RichTextBox();
		this.mnuRichText = new System.Windows.Forms.ContextMenu();
		this.mnuCopy = new System.Windows.Forms.MenuItem();
		this.mnuSep1 = new System.Windows.Forms.MenuItem();
		this.mnuClear = new System.Windows.Forms.MenuItem();
		this.txtMessage = new System.Windows.Forms.TextBox();
		this.SuspendLayout();
		// 
		// btnSend
		// 
		this.btnSend.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
		this.btnSend.Enabled = false;
		this.btnSend.Location = new System.Drawing.Point(360, 248);
		this.btnSend.Name = "btnSend";
		this.btnSend.Size = new System.Drawing.Size(96, 48);
		this.btnSend.TabIndex = 1;
		this.btnSend.Text = "Send";
		this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
		// 
		// rtbChat
		// 
		this.rtbChat.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
					| System.Windows.Forms.AnchorStyles.Left)
					| System.Windows.Forms.AnchorStyles.Right)));
		this.rtbChat.ContextMenu = this.mnuRichText;
		this.rtbChat.Font = new System.Drawing.Font("Tahoma", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
		this.rtbChat.Location = new System.Drawing.Point(8, 8);
		this.rtbChat.Name = "rtbChat";
		this.rtbChat.ReadOnly = true;
		this.rtbChat.Size = new System.Drawing.Size(448, 232);
		this.rtbChat.TabIndex = 5;
		this.rtbChat.TabStop = false;
		this.rtbChat.Text = "";
		// 
		// mnuRichText
		// 
		this.mnuRichText.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuCopy,
            this.mnuSep1,
            this.mnuClear});
		this.mnuRichText.Popup += new System.EventHandler(this.mnuRichText_Popup);
		// 
		// mnuCopy
		// 
		this.mnuCopy.Index = 0;
		this.mnuCopy.Text = "Copy";
		this.mnuCopy.Click += new System.EventHandler(this.mnuCopy_Click);
		// 
		// mnuSep1
		// 
		this.mnuSep1.Index = 1;
		this.mnuSep1.Text = "-";
		// 
		// mnuClear
		// 
		this.mnuClear.Index = 2;
		this.mnuClear.Text = "Clear";
		this.mnuClear.Click += new System.EventHandler(this.mnuClear_Click);
		// 
		// txtMessage
		// 
		this.txtMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
					| System.Windows.Forms.AnchorStyles.Right)));
		this.txtMessage.Location = new System.Drawing.Point(8, 248);
		this.txtMessage.Multiline = true;
		this.txtMessage.Name = "txtMessage";
		this.txtMessage.Size = new System.Drawing.Size(344, 48);
		this.txtMessage.TabIndex = 0;
		this.txtMessage.Enter += new System.EventHandler(this.txtMessage_Enter);
		this.txtMessage.TextChanged += new System.EventHandler(this.txtMessage_TextChanged);
		// 
		// MessageWindow
		// 
		this.AcceptButton = this.btnSend;
		this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
		this.ClientSize = new System.Drawing.Size(464, 304);
		this.Controls.Add(this.txtMessage);
		this.Controls.Add(this.rtbChat);
		this.Controls.Add(this.btnSend);
		this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
		this.KeyPreview = true;
		this.MinimumSize = new System.Drawing.Size(300, 200);
		this.Name = "MessageWindow";
		this.ShowInTaskbar = false;
		this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
		this.Text = "Chat";
		this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MessageWindow_FormClosing);
		this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MessageWindow_KeyDown);
		this.ResumeLayout(false);
		this.PerformLayout();

	}

	#endregion

	public event ShouldBroadcastTextEventHandler ShouldBroadcastText;
	public delegate void ShouldBroadcastTextEventHandler(string Text);

	//====================================================================

	#region " Log messages in RichTextBox"

	public void Log(string Text, System.Drawing.Color TextColor)
	{
		// The length of existing text.
		int EndPosition = rtbChat.TextLength;

		// The new text being added.
		StringBuilder sb = new StringBuilder(Text.Length + 10);
		sb.Append("[");
		sb.Append(DateTime.Now.ToShortTimeString());
		sb.Append("] ");
		sb.Append(Text);
		sb.Append(Environment.NewLine);
		// OS-independent NewLine character(s)
		string NewText = sb.ToString();

		// prevent RichTextBox from flickering...
		if (this.Visible) Win32API.LockWindowUpdate(rtbChat.Handle.ToInt32());

		// Append new message to the bottom
		rtbChat.AppendText(NewText);
		rtbChat.SelectionStart = EndPosition;
		rtbChat.SelectionLength = NewText.Length;
		rtbChat.SelectionColor = TextColor;
		rtbChat.SelectionStart = rtbChat.TextLength - 1;

		// Use the special trick to scroll the RichTextBox to the end.
		// Default Microsoft implementation doesn't allow to do it
		// in a simple way, without focusing the text box.
		Win32API.ScrollTextBoxToEnd(rtbChat.Handle, rtbChat.Height);

		// don't forget to enable back the RichTextBox update
		if (this.Visible) Win32API.LockWindowUpdate(IntPtr.Zero.ToInt32());
	}

	// no parameters version
	public void Log(string Text)
	{
		Log(Text, SystemColors.WindowText);
	}

	#endregion

	#region " RichTextBox context menu events "

	private void mnuCopy_Click(object sender, System.EventArgs e)
	{
		rtbChat.Copy();
	}

	private void mnuClear_Click(object sender, System.EventArgs e)
	{
		rtbChat.Clear();
	}

	#endregion

	#region " Send button "

	//====================================================================
	// Enable Send button
	//====================================================================

	private void txtMessage_TextChanged(object sender, System.EventArgs e)
	{
		EnableSend();
	}

	private void txtMessage_Enter(object sender, System.EventArgs e)
	{
		EnableSend();
	}

	private void EnableSend()
	{
		btnSend.Enabled = txtMessage.TextLength > 0;
	}

	//====================================================================
	// Send
	//====================================================================

	private void btnSend_Click(object sender, System.EventArgs e)
	{
		if (this.Visible && btnSend.Enabled)
		{
			Send();
		}
	}

	private void Send()
	{
		Log(txtMessage.Text, modMain.colMe);
		if (ShouldBroadcastText != null) {
			ShouldBroadcastText(txtMessage.Text);
		}
		txtMessage.Clear();
		txtMessage.Focus();
	}

	//====================================================================

	#endregion

	//====================================================================

	#region " Window behaviour "

	//====================================================================
	// Show the form explicitly to create its native window and to start its message loop
	// Prepare ChatWindow to be showable.
	// This creates the native window physically and implicitly launches its message loop.
	//====================================================================
	public void InitializeWindow()
	{
		this.Opacity = 0;
		this.Show();
		this.Hide();
		this.Opacity = 1;
	}

	#region " Closing the form "

	// Reason for closing the form 
	private bool ClosedFromUI = false;

	//====================================================================
	// Form Close behavior. Because this form isn't the main form, its closing
	// should be equivalent to its minimizing.
	//====================================================================

	private void MessageWindow_FormClosing(object sender, FormClosingEventArgs e)
	{
		if (ClosedFromUI)
		{
			e.Cancel = true;
			MinimizedToTray = true;
			ClosedFromUI = false;
		}
	}

	//====================================================================
	// Subclassing to spy on some useful window messages
	//====================================================================

	private const Int32 SC_CLOSE = 61536;
	private const long SC_MINIMIZE = 61472l;
	private const Int32 WM_SYSCOMMAND = 274;

	protected override void WndProc(ref System.Windows.Forms.Message m)
	{
		if (m.Msg == WM_SYSCOMMAND)
		{
			if (m.WParam.ToInt32() == SC_CLOSE)
			{
				// Close button of the form pushed.
				ClosedFromUI = true;
			}
			else if (m.WParam.ToInt32() == SC_MINIMIZE) {
				// Minimize button pushed.
				MinimizedToTray = true;
				return;
			}
		}
		base.WndProc(ref m);
	}

	//====================================================================

	#endregion

	#region " Minimize and Restore "

	//====================================================================
	// Minimize and Restore
	//====================================================================

	private void MessageWindow_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
	{
		switch (e.KeyCode) {
			case Keys.Escape:
				MinimizeToTray();
				break;
		}
	}

	//====================================================================

	public bool MinimizedToTray {
		get { return !this.Visible; }
		set {
			if (value) MinimizeToTray(); 			else Restore(); 
		}
	}

	//====================================================================

	private void MinimizeToTray()
	{
		if (this.Visible) this.Hide(); 
	}

	private void Restore()
	{
		if (!this.Visible)
		{
			this.Show();
			this.Activate();
			// do I need this?
		}
		if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal; 
		this.txtMessage.Focus();
	}

	private void mnuRichText_Popup(object sender, EventArgs e)
	{

	}

	//====================================================================

	#endregion

	//====================================================================

	#endregion

	//====================================================================

}
